home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
CBGRX100.ARJ
/
VMALLOC.C
< prev
next >
Wrap
Text File
|
1992-04-10
|
4KB
|
140 lines
/**
** VMALLOC.C
**
** Copyright (C) 1992, Csaba Biegl
** 820 Stirrup Dr, Nashville, TN, 37221
** csaba@vuse.vanderbilt.edu
**
** This file is distributed under the terms listed in the document
** "copying.cb", available from the author at the address above.
** A copy of "copying.cb" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.cb".
** You should also have received a copy of the GNU General Public
** License along with this program (it is in the file "copying");
** if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
** Cambridge, MA 02139, USA.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**/
#include "gmalloc.h"
typedef struct _vnode_ {
struct _vnode_ *next;
char far *addr;
unsigned int size;
} vnode;
static vnode *freelist = NULL; /* list of free memory blocks */
static vnode *usedlist = NULL; /* list of used memory blocks */
static vnode *nodelist = NULL; /* list of available nodes */
#define NODEALLOC 10 /* allocate this many nodes at once */
#define MINSIZE 16 /* smallest block size */
static vnode *getnode(void)
{
vnode *np;
int count;
if(nodelist == NULL) {
np = _GrMalloc(sizeof(vnode) * NODEALLOC);
if(np == NULL) return(NULL);
for(count = NODEALLOC; --count >= 0; np++) {
np->next = nodelist;
nodelist = np;
}
}
np = nodelist;
nodelist = np->next;
return(np);
}
void _GrVidMemInit(char far *start,unsigned int size)
{
vnode *np;
if(freelist != NULL) {
for(np = freelist; np->next != NULL; np = np->next);
np->next = nodelist;
nodelist = freelist;
freelist = NULL;
}
if(usedlist != NULL) {
for(np = usedlist; np->next != NULL; np = np->next);
np->next = nodelist;
nodelist = usedlist;
usedlist = NULL;
}
if((size > MINSIZE) && ((np = getnode()) != NULL)) {
np->next = NULL;
np->addr = start;
np->size = size;
freelist = np;
}
}
char far *_GrVidAlloc(unsigned int size)
{
vnode *np,*new,*prev;
for(np = freelist,prev = NULL; np != NULL; prev = np,np = np->next) {
if(np->size >= size) {
if((np->size >= (size + MINSIZE)) && ((new = getnode()) != NULL)) {
new->size = size;
new->addr = np->addr + (np->size - size);
np->size -= size;
new->next = usedlist;
usedlist = new;
return(new->addr);
}
*((prev == NULL) ? &freelist : &prev->next) = np->next;
np->next = usedlist;
usedlist = np;
return(np->addr);
}
}
return((char far *)NULL);
}
void _GrVidFree(char far *addr)
{
vnode *np,*fp,*prev;
for(np = usedlist,prev = NULL; ; prev = np,np = np->next) {
if(np == NULL) return;
if(np->addr == addr) break;
}
*((prev == NULL) ? &usedlist : &prev->next) = np->next;
for(fp = freelist,prev = NULL; fp != NULL; prev = fp,fp = fp->next) {
if(fp->addr > np->addr) {
if(fp->addr == (np->addr + np->size)) {
fp->size += np->size;
fp->addr = np->addr;
np->next = nodelist;
nodelist = np;
np = fp;
fp = fp->next;
}
break;
}
}
np->next = fp;
if(prev == NULL)
freelist = np;
else if(np->addr != (prev->addr + prev->size))
prev->next = np;
else {
prev->size += np->size;
prev->addr = np->addr;
prev->next = fp;
np->next = nodelist;
nodelist = np;
}
}